﻿<!--
> Muaz Khan     - https://github.com/muaz-khan 
> MIT License   - https://www.webrtc-experiment.com/licence/
> Experiments   - https://github.com/muaz-khan/WebRTC-Experiment
-->
<!DOCTYPE html>
<html lang="en">
    <head>
        <title>WebRTC for Beginners | Muaz Khan</title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
        <link rel="author" type="text/html" href="https://plus.google.com/+MuazKhan">
        <meta name="author" content="Muaz Khan">
        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
        <link rel="stylesheet" href="https://cdn.webrtc-experiment.com/style.css">
        
        <style>
            p { padding: .8em; }

            li {
                border-bottom: 1px solid rgb(189, 189, 189);
                border-left: 1px solid rgb(189, 189, 189);
                padding: .5em;
            }

            code {
                color: red;
                font-family: inherit;
            }

            table { background: white; }

            td {
                border: 0;
                padding: 0;
            }
        </style>
        <script>
            document.createElement('article');
            document.createElement('footer');
        </script>
    


        <script type="text/javascript" src="https://cdn.webrtc-experiment.com/syntax/sh_main.min.js"> </script>
        <script type="text/javascript" src="https://cdn.webrtc-experiment.com/syntax/sh_javascript.min.js"> </script>
        <script type="text/javascript" src="https://cdn.webrtc-experiment.com/syntax/sh_html.min.js"> </script>
        <link type="text/css" rel="stylesheet" href="https://cdn.webrtc-experiment.com/syntax/sh_style.css">
		
    </head>

    <body onload="sh_highlightDocument();">
        <article>
            <header style="text-align: center;">
                <h1>
                    WebRTC for Beginners
                </h1>            
                <p>
                    <a href="https://www.webrtc-experiment.com/">HOME</a>
                    <span> &copy; </span>
                    <a href="http://www.MuazKhan.com/" target="_blank">Muaz Khan</a>
                    
                    .
                    <a href="http://twitter.com/WebRTCWeb" target="_blank" title="Twitter profile for WebRTC Experiments">@WebRTCWeb</a>
                    
                    .
                    <a href="https://github.com/muaz-khan?tab=repositories" target="_blank" title="Github Profile">Github</a>
                    
                    .
                    <a href="https://github.com/muaz-khan/WebRTC-Experiment/issues?state=open" target="_blank">Latest issues</a>
                    
                    .
                    <a href="https://github.com/muaz-khan/WebRTC-Experiment/commits/master" target="_blank">What's New?</a>
                </p>
            </header>

            <div class="github-stargazers"></div>

            <blockquote style="background: #f3b7b7;border: 5px solid black;border-radius: 5px;">
                This tutorial is <span style="border: 1px dotted red; background: yellow; padding: 2px 5px;">out-dated (written in 2013)</span>. Please check this tutorial instead: <a href="https://codelabs.developers.google.com/codelabs/webrtc-web/#0">https://codelabs.developers.google.com/codelabs/webrtc-web/#0</a>
            </blockquote>
            
            <section class="experiment">
                <h2 class="header">Suggestions</h2>
                <ol>
                    <li>
                        If you're newcomer, newbie or beginner; you're suggested to try <a href="http://www.rtcmulticonnection.org/docs/" target="_blank">RTCMultiConnection.js</a> or <a href="https://github.com/muaz-khan/WebRTC-Experiment/tree/master/DataChannel" target="_blank">DataChannel.js</a> libraries.
                    </li>
                </ol>
		
            </section>
		
            <section class="experiment">
                <h2 class="header">Getting USER MEDIA using Chrome media capture APIs</h2>
                <p>
                    First of all: you need to get access to microphone and camera if you want to build a video streaming app.
                </p>
                <pre class="sh_javascript">
var <a href="#addStream" title="To allow your friend hear your voice and see you: we will share your microphone and camera.">streamToAttach</a>;
navigator.<strong id="webkitGetUserMedia" title="This API allows us access to your microphone and camera.">webkitGetUserMedia</strong>({ audio: <strong title="Allowing access to microphone.">true</strong>, video: <strong title="Allowing access to camera.">true</strong> }, function (stream) {
    video.src = webkitURL.<strong>createObjectURL</strong>(stream);
    <a id="streamToAttach" href="#addStream">streamToAttach</a> = stream;
}, function(error) {
    alert(error);
});
</pre>
            </section>
			
            <section class="experiment">
                <h2 class="header">Getting USER MEDIA using Firefox media capture APIs</h2>
                <pre class="sh_javascript">
var <a href="#addStream" title="To allow your friend hear your voice and see you: we will share your microphone and camera.">streamToAttach</a>;
navigator.<strong id="mozGetUserMedia" title="This API allows us access to your microphone and camera.">mozGetUserMedia</strong>({ audio: <strong title="Allowing access to microphone.">true</strong>, video: <strong title="Allowing access to camera.">true</strong> }, function (stream) {
    video.mozSrcObject = stream;
    video.play();
    <a id="A1" href="#addStream">streamToAttach</a> = stream;
}, function(error) {
    alert(error);
});
</pre>
            </section>
			
            <section class="experiment">
                <p>
                    There are following possible situations:
                </p>
				
                <ol>
                    <li>A person wants to share camera with his friend(s): so, he will make an offer to his friend to join him. 
                        <br />
                        He is the <a href="#offerer">offerer</a>.
                    </li>
                    <li>A person who receives an offer from a friend: so, he will join him. He is the <a href="#answerer">answerer</a>.
                    </li>
                </ol>
                        
				
                <p>
                    There are so many other possible situations. Let go to the point.
                </p>
            </section>
			
            <section class="experiment">
                <h2 class="header">Offerer</h2>
                <p>
                    The first situation: a person wants to make an offer request to his friend. He will create <a href="#offer-sdp">offer sdp</a> and send that <a href="#offer-sdp">sdp</a> to his friend.
                </p>
                <p>
                    First of all: we need to open a peer connection:
                </p>
					
                <pre class="sh_javascript">
var <span id="peerConnection">peerConnection</span> = new <strong id="Strong1" title="Initializing RTCPeerConnection object. You'll do this both for offerer and answerer.">webkitRTCPeerConnection</strong>(
    { "<strong title="ICE servers for NAT traversing">iceServers</strong>": [{ "url": "<strong title="Using STUN as ICE server for NAT traversing">stun</strong>:stun.l.google.com:19302" }] }
);
</pre>
                <p>
                    <a href="#peerConnection">webkitRTCPeerConnection</a> (or <strong title="Currently, Firefox ignores both arguments!">mozRTCPeerConnection</strong>) constructor takes two objects (arguments):
                </p>
                <ol>
                    <li>ICE servers (STUN or TURN)
                    </li>
                    <li>
                        <strong>Optional</strong> (like <a href="/docs/how-to-use-rtcdatachannel.html">RtpDataChannels</a>)
                    </li>
                </ol>
                    
                <p>
                    For Firefox, you can use this STUN server: <br />{ "<strong title="ICE servers for NAT traversing">iceServers</strong>": [{ "url": "<strong title="Using STUN as ICE server for NAT traversing">stun</strong>:stun.services.mozilla.com" }] }
                </p>
					
                <p>
                    Setting event handlers for <a href="#peerConnection">peer connection</a> object:
                </p>
					
                <pre class="sh_javascript">
<a href="#peerConnection">peerConnection</a>.<strong title="On getting locally generated ICE candidates: You'll post these locally generated ICE to other peer; so he can add them and ask peer connection object to recognize suitable ICE candidate and complete the handshake.">onicecandidate</strong> = <a href="#onicecandidate-func" id="onicecandidate">onicecandidate</a>;
<a href="#peerConnection">peerConnection</a>.<strong title="This event fires on getting first clue of remote stream. You should wait until remote stream starts flowing.">onaddstream</strong> = <a href="#onaddstream-func" id="onaddstream">onaddstream</a>;
<a href="#peerConnection">peerConnection</a>.<strong id="addStream" title="Attaching your local stream (your microphone and camera)">addStream</strong> (<a href="#streamToAttach">streamToAttach</a>);
</pre>

                <p>
                    In simple words: <a href="#onicecandidate-func">onicecandidate</a> returns locally generated ICE candidates so you can pass them over other peer(s) via XHR or Socket.
                </p>
                
                <li>
                    "locally-generated" means ice candidates that are trickled or gathered for your peer object; i.e. list of ice candidates that are returned by STUN/TURN servers; these ice candidates contains your public ipv4/ipv6 addresses as well as UDP random addresses; you need to share these ice candidates with target peer so WebRTC ICE Agent can use your ports to setup your connection with target peer!
                </li>
                
                <p>
                    <a href="#onaddstream-func">onaddstream</a> returns remote stream (microphone and camera of your friend!).
                </p>
                <p>
                    <a href="#peerConnection">peerConnection</a>.<a href="#streamToAttach">addStream</a> attaches your local microphone and camera for other peer.
                </p>
					
					
            </section>
			
            <section class="experiment">
                <h2 class="header">Creating Offer SDP</h2>
				
                <pre class="sh_javascript">
<a href="#peerConnection">peerConnection</a>.<strong id="offerer">createOffer</strong>(function (sessionDescription) {
    <a href="#peerConnection">peerConnection</a>.<strong>setLocalDescription</strong>(sessionDescription);

    <span class="comment" id="offer-sdp" title="Offerer generated Offer SDP. So, now you should transfer that SDP on the answerer side. Answer will set his remote description using offer sdp.">// POST-Offer-SDP-For-Other-Peer(sessionDescription.<strong>sdp</strong>, sessionDescription.<strong>type</strong>);</span>

}, function(error) {
    alert(error);
}, { '<strong>mandatory</strong>': { '<strong>OfferToReceiveAudio</strong>': true, '<strong>OfferToReceiveVideo</strong>': true } });
</pre>
            </section>
			
            <section class="experiment">
                <h2 class="header">Answerer</h2>
                <p>
                    Assume that you sent <a href="#offer-sdp">offer sdp</a> to your friend using XHR. Now, "process" that <a href="#offer-sdp">offer sdp</a> and then create <a href="#answer-sdp">answer sdp</a> and send <a href="#answer-sdp">it</a> back to <a href="#answer-sdp-for-offerer">offerer</a>:
                </p>
            </section>
			
            <section class="experiment">
                <h2 class="header">setRemoteDescription!</h2>
                <pre class="sh_javascript">
<a href="#peerConnection">peerConnection</a>.<strong>setRemoteDescription</strong>(new <strong>RTCSessionDescription</strong>(<a href="#offer-sdp">offerSDP</a>));
</pre>
            </section>
			
            <section class="experiment">
                <h2 class="header">And to createAnswer...</h2>
                <pre class="sh_javascript">
<a href="#peerConnection">peerConnection</a>.<strong id="answerer">createAnswer</strong>(function (sessionDescription) {
    <a href="#peerConnection">peerConnection</a>.<strong>setLocalDescription</strong>(sessionDescription);
    
    <span class="comment" id="answer-sdp" title="Answerer generated the Answer SDP. So, now you should transfer that SDP on the offerer side. Offer will set his remote description using answer sdp and complete the handshake.">// POST-answer-SDP-back-to-Offerer(sessionDescription.<strong>sdp</strong>, sessionDescription.<strong>type</strong>);</span>

}, function(error) {
    alert(error);
}, { '<strong>mandatory</strong>': { '<strong>OfferToReceiveAudio</strong>': true, '<strong>OfferToReceiveVideo</strong>': true } });
</pre>

                <p id="answer-sdp-for-offerer">Offerer received <a href="#answer-sdp">answer sdp</a> from <a href="#answerer">answerer</a></p>
            </section>
			
            <section class="experiment">
                <h2 class="header">setRemoteDescription!</h2>
                <pre class="sh_javascript">
<a href="#peerConnection">peerConnection</a>.<strong>setRemoteDescription</strong>(new <strong>RTCSessionDescription</strong>(<a href="#answer-sdp">answerSDP</a>));
</pre>
            </section>
			
            <section class="experiment">
                <p>
                    <a href="#offer-sdp">Offer</a>/<a href="#answer-sdp">Answer</a> exchange is done. What remaining is ICE candidates.
                </p>
            </section>
			
            <section class="experiment">
                <h2 class="header">On getting locally generated ICE</h2>
                <pre class="sh_javascript">
function <a href="#onicecandidate" id="onicecandidate-func">onicecandidate</a>(event) {
    if (!<a href="#peerConnection">peerConnection</a> || !event || !event.candidate) return;
    var candidate = event.<strong>candidate</strong>;
    <span class="comment" id="Span1" title="Local ICE candidates are generated. Now, you should pass these ICE on the other side and let other peer to add these ICE.">// POST-ICE-to-other-Peer(candidate.<strong>candidate</strong>, candidate.<strong>sdpMLineIndex</strong>);</span>
}
</pre>
            </section>
			
            <section class="experiment">
                <h2 class="header">On getting ICE sent by other peer</h2>
                <pre class="sh_javascript">
<a href="#peerConnection">peerConnection</a>.<strong id="addIceCandidate">addIceCandidate</strong>(new <strong>RTCIceCandidate</strong>({
    <strong>sdpMLineIndex</strong>: candidate.<strong>sdpMLineIndex</strong>,
    <strong>candidate</strong>: candidate.<strong>candidate</strong>
}));
</pre>
            </section>
			
            <section class="experiment">
                <h2 class="header"><a href="#onaddstream">onaddstream</a> event handling</h2>
                <pre class="sh_javascript">
function <a href="#onaddstream" id="onaddstream-func">onaddstream</a>(event) {
    if (!event) return;
    remote_video.src = webkitURL.<strong>createObjectURL</strong>(event.<strong>stream</strong>);
    // remote_video.mozSrcObject  = event.<strong>stream</strong>;
}
</pre>
            </section>
			
            <section class="experiment">
                <h2 class="header">Wait until <a href="#onaddstream">remote stream</a> starts flowing</h2>
                <pre class="sh_javascript">
function <a href="#onaddstream" id="A2">onaddstream</a>(event) {
    if (!event) return;
    remote_video.src = webkitURL.<strong>createObjectURL</strong>(event.<strong>stream</strong>);
    // remote_video.mozSrcObject  = event.<strong>stream</strong>;
    
    <a href="#waitUntilRemoteStreamStartsFlowing">waitUntilRemoteStreamStartsFlowing</a>();
}
</pre>
            </section>
			
            <section class="experiment">
                <pre class="sh_javascript">
function <strong id="waitUntilRemoteStreamStartsFlowing">waitUntilRemoteStreamStartsFlowing</strong>()
{
    if (!(remote_video.<strong>readyState</strong> &lt;= HTMLMediaElement.<strong>HAVE_CURRENT_DATA</strong> 
        || remote_video.<strong>paused</strong> || remote_video.<strong>currentTime</strong> &lt;= 0)) 
    {
        <span class="comment" id="remote-stream-started-flowing">// remote stream started flowing!</span>
    } 
    else <strong>setTimeout</strong>(<a href="#waitUntilRemoteStreamStartsFlowing">waitUntilRemoteStreamStartsFlowing</a>, 50);
}
</pre>
            </section>
            
            <section class="experiment">
                <h2 class="header" id="single-page-demos">Single Page Demos</h2>
                <ol>
                    <li>
                        <a href="https://www.webrtc-experiment.com/demos/client-side.html">Simplest Example!</a>
                    </li>
                    
                    <li>
                        <a href="https://www.webrtc-experiment.com/demos/client-side-socket-io.html">Simple Demo using Socket.io</a>
                    </li>
                    
                    <li>
                        <a href="https://www.webrtc-experiment.com/demos/client-side-websocket.html">Simple Demo using WebSocket</a>
                    </li>
                    
                    <li>
                        <a href="https://www.webrtc-experiment.com/demos/">A few other single-page demos can be found here</a>
                    </li>
                </ol>
            </section>
            
            <section class="experiment">
                <h2 class="header" id="real-demos">Real Demos</h2>
                <ol>
                    <li>
                        <a href="https://www.webrtc-experiment.com/websocket/">Simple demo using WebSockets</a> / <a href="https://github.com/muaz-khan/WebRTC-Experiment/tree/master/websocket">Source Code</a>
                    </li>
                    
                    <li>
                        <a href="https://www.webrtc-experiment.com/socket.io/">Simple demo using Socket.io</a> / <a href="https://github.com/muaz-khan/WebRTC-Experiment/tree/master/socket.io">Source Code</a>
                    </li>
                </ol>
            </section>
			
            <section class="experiment">
                <h2 class="header" id="other-tutorials">Other Tutorials</h2>
                <ol>
                    <li>
                        Are you interested in a "more" simple full-fledged guide? Read <a href="https://www.webrtc-experiment.com/docs/how-to-use-rtcpeerconnection-js-v1.1.html">this tutorial</a>.
                    </li>
                    
                    <li>
                        Are you interested in a "more" detailed guide? Read <a href="https://www.webrtc-experiment.com/docs/webrtc-for-newbies.html">this tutorial</a>.
                    </li>
                    
                    <li>
                        You can find many tutorials here: <a href="https://www.webrtc-experiment.com/#documentations">https://www.webrtc-experiment.com/#documentations</a>
                    </li>
                </ol>
            </section>
        
            <section class="experiment own-widgets latest-commits">
                <h2 class="header" id="updates" style="color: red; padding-bottom: .1em;"><a href="https://github.com/muaz-khan/WebRTC-Experiment/commits/master" target="_blank">Latest Updates</a></h2>
                <div id="github-commits"></div>
            </section>
        
            <section class="experiment">
                <h2 class="header" id="feedback">Feedback</h2>
                <div>
                    <textarea id="message" style="border: 1px solid rgb(189, 189, 189); height: 8em; margin: .2em; outline: none; resize: vertical; width: 98%;" placeholder="Have any message? Suggestions or something went wrong?"></textarea>
                </div>
                <button id="send-message" style="font-size: 1em;">Send Message</button><small style="margin-left: 1em;">Enter your email too; if you want "direct" reply!</small>
            </section>
            
        </article>
        
        <a href="https://github.com/muaz-khan/WebRTC-Experiment" class="fork-left"></a>
        
        <footer>
            <p>
                <a href="https://www.webrtc-experiment.com/">WebRTC Experiments</a>
                © <a href="https://plus.google.com/+MuazKhan" rel="author" target="_blank">Muaz Khan</a>
                <a href="mailto:muazkh@gmail.com" target="_blank">muazkh@gmail.com</a>
            </p>
        </footer>
    
        <!-- commits.js is useless for you! -->
        <script src="https://cdn.webrtc-experiment.com/commits.js" async> </script>
    </body>
</html>
